package exercise;

import java.util.concurrent.atomic.AtomicInteger;

public class Exercise007 { 
    public static void main(String[] args) {
        // test01();
        // test02();
        // test03();
        test04();
        // test05();

    }
    public static void test01(){
        // 给定一个很长的数组 (长度 1000w), 通过随机数的方式生成 1-100 之间的整数.
        // 实现代码, 能够创建两个线程, 对这个数组的所有元素求和. 
        // 其中线程1 计算偶数下标元素的和, 线程2 计算奇数下标元素的和.
        // 最终再汇总两个和, 进行相加.
        // 记录程序的执行时间.
        int[] arr = new int[10000000];
        for(int i = 0;i < arr.length;i++){
            arr[i] = (int)(Math.random()*100);
        }
        long start = System.currentTimeMillis();
        AtomicInteger sum1 = new AtomicInteger(0);
        AtomicInteger sum2 = new AtomicInteger(0);
        Thread t1 = new Thread(()->{
            int sum = 0;
            for(int i = 0;i < arr.length;i += 2){
                sum += arr[i];
            }
            sum1.set(sum);
        });
        Thread t2 = new Thread(()->{
            int sum = 0;
            for(int i = 1;i < arr.length;i += 2){
                sum += arr[i];
            }
            sum2.set(sum);
        });
        try {
            t1.start();
            t2.start();
            t1.join();
            t2.join();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        int sum = sum1.get() + sum2.get();
        System.out.println(sum);
        long end = System.currentTimeMillis();
        System.out.println(end-start);
    }
    public static void test02(){
        // 有20个线程，需要同时启动.
        // 每个线程按0-19的序号打印，如第一个线程需要打印0.
        // 请设计代码，在main主线程中，等待所有子线程执行完后，再打印 ok.
        Thread[] threads = new Thread[20];
        for(int i = 0; i < threads.length; i++){
            // 创建局部变量保存当前i值，使其成为effectively final   
            final int threadNumber = i;
            threads[i] = new Thread(()->{
                System.out.println(threadNumber);
            });
        }
        for(Thread t:threads){
            t.start();
        }
        try {
            for(Thread t:threads){
                t.join();
            }
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("ok");
    }
    public static void test03(){
        Thread t = new Thread(new Runnable() {
            @Override
            public void run() {
                System.out.println("1");
            }
        });
        t.start();
        System.out.println("2");
    } 
    static int count = 0;
    public static void test04(){
        Object locker = new Object();

        Thread t1 = new Thread(()->{
            System.out.println("t1开始");
            for(int i = 0;i < 10000;i++){
                synchronized(locker){
                    count++;
                }
            }
            System.out.println("t1结束");
        });
        Thread t2 = new Thread(()->{
            System.out.println("t2开始");
            for(int i = 0;i < 10000;i++){
                synchronized(locker){
                    count++;
                }
            }
            System.out.println("t2结束");
        });

        t1.start();
        t2.start();
        try {
            t1.join();
            t2.join();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println(count);
    }
    public static void test05(){
        Object locker1 = new Object();
        Object locker2 = new Object();

        Thread t1 = new Thread(()->{
            System.out.println("t1开始");
            synchronized(locker1){
                System.out.println("t1进入locker1");
                try {
                    locker1.wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                synchronized(locker2){
                    System.out.println("t1试图获取locker2");
                    locker2.notify();
                }
            }
            System.out.println("t1结束");
        });
        Thread t2 = new Thread(()->{
            System.out.println("t2开始");
            synchronized(locker2){
                System.out.println("t2进入locker2");
                try {
                    locker2.wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                synchronized(locker1){
                    System.out.println("t2试图获取locker1");
                    locker1.notify();
                }
            }
            System.out.println("t2结束");
        });

        t1.start();
        t2.start();
        try{
            Thread.sleep(1000);
        }catch(InterruptedException e){
            e.printStackTrace();
        }
        System.out.println("t1线程状态:"+t1.getState());
        System.out.println("t2线程状态:"+t2.getState());
        try {
            t1.join();
            t2.join();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }            
}
